package org.domain.sigepac.validator;

import java.lang.annotation.Annotation;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.hibernate.mapping.Property;
import org.hibernate.validator.PropertyConstraint;
import org.hibernate.validator.Validator;
import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.framework.EntityHome;

@Name("UniqueValidator")
public class UniqueValidator implements Validator, PropertyConstraint {

	// Entity for which validation is to be fired
	private String targetEntity;

	// Field for which validation is to be fired.
	private String field;

	// IdField for which validation is to be fired.
	private String idField;

	// Id of Field for which validation is to be fired.
	private String[] idProvider;

	public boolean isValid(Object value) {
		EntityManager entityManager = (EntityManager) Component
				.getInstance("entityManager");
		// looking for the entityHome who manages the entity i'm interested in

		Query query = entityManager.createQuery("select t from " + targetEntity
				+ " t where t." + field + " = :value and " + idField + "<>:id");

		EntityHome entityHome=null;
		for(String provider:idProvider){

			entityHome = (EntityHome) Component.getInstance(provider,false);

			if (entityHome != null && entityHome.getId() != null)
				break;

		}

		if(entityHome==null)
			return true;

		if (entityHome != null && entityHome.getId() != null) {
			query.setParameter("value", value);
			query.setParameter("id", entityHome.getId());
		} else {

			query = entityManager.createQuery("select t from " + targetEntity
					+ " t where t." + field + " = :value");
			query.setParameter("value", value);
		}
		try {
			if (query.getResultList() != null
					&& query.getResultList().size() > 0) {
				return false;
			}
			return true;
		} catch (final NoResultException e) {
			return true;
		}
	}

	public void apply(Property arg0) {

	}

	public void initialize(Annotation parameters) {
		targetEntity = ((Unique) parameters).entityName();
		field = ((Unique) parameters).fieldName();
		idField = ((Unique) parameters).idFieldName();
		idProvider = ((Unique) parameters).idProvider();
	}
}